package com.dingding.common.core.util.tools.wechat;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dingding.common.core.util.HttpTool;
import com.dingding.common.core.util.MD5Util;
import com.dingding.common.core.util.SHA1Util;
import com.dingding.common.core.util.ToolUtil;
import com.dingding.common.core.util.UrlMaker;
import com.dingding.common.core.util.tools.wechat.pay.paybean.SecondSign;

/**
 * @ClassName: WechatTool
 * @Description: 微信有关工具类
 * @author fengshuonan
 * @date 2016年2月24日 上午9:32:24
 * @version 叮叮搭车2.0
 */
public class WechatTool {

	private static Logger log = Logger.getLogger(WechatTool.class);

	/**
	 * @Description: 通过微信返回给url的code获取用户的openId
	 * @author fengshuonan
	 */
	public static String getOpenIDByCode(String code) {

		if (ToolUtil.isNotBlank(code)) {
			String url = UrlMaker.getOpenidByCodeUrl(code);
			JSONObject jsonObject = HttpTool.loadJson(url);

			if (jsonObject != null) {
				String openid = (String) jsonObject.get("openid");
				return openid;
			}
		}
		return null;
	}

	/**
	 * @Title: getAccessToken
	 * @Description: 请求access token，获取真正access token时不要调用此方法
	 * @author fengshuonan
	 * @return String access token
	 * @throws
	 */
	public static String requestAccessToken() {

		String requestUrl = UrlMaker.getWechatAccessTokenUrl();
		String json = HttpTool.requestUrl(requestUrl);
		JSONObject jsonObj = JSON.parseObject(json);

		if (jsonObj != null && jsonObj.containsKey("access_token")) {
			String access_token = (String) jsonObj.get("access_token");
			int expiredTime = jsonObj.getInteger("expires_in");
			WechatCode.currentAccessToken = access_token;
			WechatCode.accTokExpiredTime = new Date(System.currentTimeMillis() + 1000 * expiredTime);// 设置新的access_token过期时间
			return access_token;
		} else {
			log.error("请求服务器获取access_token出错！内容为:" + json);
			return "error";
		}
	}

	/**
	 * @Title: requestJsapiTicket
	 * @Description: 请求jsapi_ticket，获取真正jsapi_ticket时不要调用此方法
	 * @author fengshuonan
	 * @return String jsapi_ticket
	 * @throws
	 */
	public static String requestJsapiTicket() {

		String requestUrl = UrlMaker.getWechatJsapiUrl();
		String json = HttpTool.requestUrl(requestUrl);
		JSONObject jsonObj = JSON.parseObject(json);

		if (jsonObj != null && jsonObj.containsKey("ticket")) {
			String ticket = (String) jsonObj.get("ticket");
			int expiredTime = jsonObj.getInteger("expires_in");
			WechatCode.jsapi_ticket = ticket;
			WechatCode.jsapiExpiredTime = new Date(System.currentTimeMillis() + 1000 * expiredTime);// 设置新的access_token过期时间
			return ticket;
		} else {
			log.error("请求服务器获取jsapi_ticket出错！内容为:" + json);
			return "error";
		}
	}

	/**
	 * @Title: getAccessToken
	 * @Description:获取微信端access_token
	 * @author fengshuonan
	 * @return String access_token
	 * @throws
	 */
	public static synchronized String getAccessToken() {

		if (ToolUtil.isBlank(WechatCode.currentAccessToken)) {
			return WechatTool.requestAccessToken();
		}
		Date now = new Date();
		Date that = WechatCode.accTokExpiredTime;

		if (now.compareTo(that) < 0) {
			return WechatCode.currentAccessToken;
		} else {
			return WechatTool.requestAccessToken();
		}
	}

	/**
	 * @Title: getJsapi_ticket
	 * @Description: 获取jsapi
	 * @author fengshuonan
	 * @return String jsapi
	 * @throws
	 */
	public static synchronized String getJsapi_ticket() {

		if (ToolUtil.isBlank(WechatCode.currentAccessToken)) {
			return WechatTool.requestJsapiTicket();
		}

		Date now = new Date();
		Date that = WechatCode.jsapiExpiredTime;

		if (now.compareTo(that) < 0) {
			return WechatCode.jsapi_ticket;
		} else {
			return WechatTool.requestJsapiTicket();
		}
	}

	/**
	 * @Title: wechatTokenCheck
	 * @Description:微信接入验证
	 * @author fengshuonan
	 * @throws
	 */
	public static boolean wechatTokenCheck(String token, String timestamp, String nonce, String signature) {

		List<String> params = new ArrayList<String>();
		params.add(token);
		params.add(timestamp);
		params.add(nonce);

		// 1. 将token、timestamp、nonce三个参数进行字典序排
		ToolUtil.lexSort(params);

		// 2. 将三个参数字符串拼接成一个字符串进行sha1加密
		String temp = SHA1Util.sha1Hex(params.get(0) + params.get(1) + params.get(2));

		if (temp.equals(signature)) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * @Description:请求服务器获取ticket的接口
	 * @param parId 创建带参数二维码需要带的参数
	 * @author fengshuonan
	 */
	public static JSONObject getWechatTicketResponse(int parId) {

		String requestJson = "{\"action_name\": \"QR_LIMIT_SCENE\", \"action_info\": {\"scene\": {\"scene_id\": "
				+ parId + "}}}";
		String url = UrlMaker.getWechatTicketUrl();
		JSONObject response = HttpTool.postJsonGetJson(url, requestJson);

		return response;
	}

	/**
	 * @Description: 获取微信ticket（用于带参数的二维码的生成）
	 * @param parId 创建带参数二维码需要带的参数
	 * @author fengshuonan
	 * @return String
	 */
	public static String getWechatTicket(int parId) {

		JSONObject jsonObject = getWechatTicketResponse(parId);

		return (jsonObject != null) ? jsonObject.getString("ticket") : null;
	}

	/**
	 * @Description:获取微信ticket（用于带参数的二维码的生成）
	 * @param parId
	 * @return
	 * @author fengshuonan
	 * @return String
	 */
	public static String getOfficialQrUrl(int parId) {

		JSONObject jsonObject = getWechatTicketResponse(parId);

		return (jsonObject != null) ? jsonObject.getString("url") : null;
	}

	
	/**
	 * @Title: getSecondSign
	 * @Description: 生成二次签名
	 * @param secondSign 二次签名所需要的参数
	 * @author fengshuonan
	 * @return String 
	 * @throws
	 */
	public static SecondSign getSecondSign(String prepayId,String nonceStr){
		
		SecondSign secondSign = new SecondSign();
		secondSign.setAppid("wx8b6d01f28792414a");
		secondSign.setPartnerid("1316301901");
		secondSign.setPrepayid(prepayId);
		secondSign.setNoncestr(nonceStr);
		
		//生成秒级别的时间戳
		Long l = new Long(String.valueOf(new Date().getTime()));
		l = l/1000;
		secondSign.setTimestamp(l.toString());
		
		//生成签名
		String apiSec = "j5axbIfMSZjsiEGAScGMCUhp5kO2Oqaj";//API安全秘钥 
		String stringSignTemp = ToolUtil.lexSortBean(secondSign, SecondSign.class,"package=Sign=WXPay") + "key=" + apiSec;
		String sign = MD5Util.md5Encrypt(stringSignTemp).toUpperCase();
		secondSign.setSign(sign);
		
		return secondSign;
	}
	
}
